home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Shareware Grab Bag
/
Shareware Grab Bag.iso
/
007
/
qbtools1.arc
/
AEBITKIL.BAS
< prev
next >
Wrap
BASIC Source File
|
1987-01-22
|
12KB
|
281 lines
rem $linesize:132
rem $title:'Application Engineer Standard Routines'
rem $subtitle:'Delete a key from the index - introduction'
'
' Major modification(s)
'
' 1) Reallocation of the key to the system.
' 2) Relinkage of the keys for the correct sequencing.
'
' ==> still needed <==
'
' 3) Balance checking of the keys during deletion.
' 4) Version to allocate 32 bit record pointers.
'
' Modifications on 7th January, 1987.
'
' More modifications on 10th January, 1987.
'
' More modifications on 22nd January, 1987.
'
' Taken out logical expressions. NOT and AND seem to behave in a
' different manner than expected. Use instead, math logical expressions.
'
' Deleting keys with parents seems to be fine. The problem is deleting
' keys where their location is record 1 in the file. To do this correctly,
' a key needs to be moved from the left side of the index and placed in
' record 1. This key then needs to have it's childrens' parents' pointers
' reallocated, and then the previous position for this record placed on the
' deletion stack.
'
' The above problem reared it's head on january 22nd. This time, when a key
' (which was in record 1) was deleted with only LEFT NODE children, the
' whole index would 'vanish' !
'
' This is indeed a bug
'
' This also happens to keys with RIGHT children ! Oh No !
'
' (c) Copyright 1986, 1987 Roy Barrow
'
'
' Key = 1
' Left = 2
' Right = 3
' Parent = 4
' Master = 5
' Delete = 6
rem $include:'AESHARED.BAS'
sub bit.kill(fl%,ky$,mrec%,success%) static
if mrec%<1 then
goto badkey
end if
if success%<1 then
goto badkey
end if
get #fl%,success% ' key to delete
dk$=xk$(fl%,1%) ' key
d.s%=success% ' position in file
d.l%=cvi(xk$(fl%,2%)) ' left pointer
d.r%=cvi(xk$(fl%,3%)) ' right pointer
d.p%=cvi(xk$(fl%,4%)) ' parent pointer
d.m%=cvi(xk$(fl%,5%)) ' pointer to ACTUAL record
d.d%=cvi(xk$(fl%,6%)) ' pointer to next deleted
if (d.p%<>0%) then ' there IS a parent
rem $subtitle:'There is a parent and a left child'
rem $page
if (d.l%<>0%) and (d.r%=0%) then ' left ONLY
get #fl%,d.p% ' get the parent
if cvi(xk$(fl%,2%))=d.s% then ' yes, link to the left
side%=2%
else
side%=3% ' otherwise, right
end if
lset xk$(fl%,side%)=mki$(d.l%) ' change the link
put #fl%,d.p% ' write it back
get #fl%,d.l% ' get the kid
lset xk$(fl%,4%)=mki$(d.p%) ' relink the child
put #fl%,d.l% ' write it back
gosub init.key.rec ' init the record
lset xk$(fl%,6%)=mki$(xh%(fl%,4%)) ' allocate on stack
put #fl%,d.s% ' write it away
xh%(fl%,4%)=d.s% ' new deleted lifo rec
end if
rem $subtitle:'There is a parent and a right child'
rem $page
if (d.r%<>0%) and (d.l%=0%) then ' right ONLY
get #fl%,d.p% ' get the parent
if cvi(xk$(fl%,2%))=d.s% then ' yes, link to the left
side%=2%
else
side%=3% ' otherwise, right
end if
lset xk$(fl%,side%)=mki$(d.r%) ' change the link
put #fl%,d.p% ' write it back
get #fl%,d.r% ' get the kid
lset xk$(fl%,4%)=mki$(d.p%) ' relink the child
put #fl%,d.r% ' write it back
gosub init.key.rec ' init the record
lset xk$(fl%,6%)=mki$(xh%(fl%,4%)) ' allocate on stack
put #fl%,d.s% ' write it away
xh%(fl%,4%)=d.s% ' new deleted lifo rec
end if
rem $subtitle:'There is a parent , but no children'
rem $page
if ((d.l%=0%) and (d.r%=0%)) then ' NO children
get #fl%,d.p% ' get the parent
if cvi(xk$(fl%,2%))=d.s% then ' yes, link to the left
side%=2%
else
side%=3% ' otherwise, right
end if
lset xk$(fl%,side%)=mki$(0%) ' change the link
put #fl%,d.p% ' write it back
gosub init.key.rec ' init the record
lset xk$(fl%,6%)=mki$(xh%(fl%,4%)) ' allocate on stack
put #fl%,d.s% ' write it away
xh%(fl%,4%)=d.s% ' new deleted lifo rec
end if
rem $subtitle:'There is a parent and both left & right children'
rem $page
if (d.l%<>0%) and (d.r%<>0%) then ' Yup, two kids
get #fl%,d.l% ' get the left
lset xk$(fl%,4%)=mki$(d.p%) ' give a new parent
put #fl%,d.l% ' write it back
pnh%=d.l% ' last key so far
nh%=cvi(xk$(fl%,3%)) ' right key
while nh%<>0% ' keep getting
get #fl%,nh% ' get right
pnh%=nh% ' last key so far
nh%=cvi(xk$(fl%,3%)) ' right key
wend
lset xk$(fl%,3%)=mki$(d.r%) ' link deleted's right to this
put #fl%,pnh% ' write this one back
get #fl%,d.r% ' get the right one
lset xk$(fl%,4%)=mki$(pnh%) ' set the new parent
put #fl%,d.r% ' write it back
get #fl%,d.p% ' fetch the parent
if cvi(xk$(fl%,2%))=d.s% then ' yes, link to the left
side%=2%
else
side%=3% ' otherwise, right
end if
lset xk$(fl%,side%)=mki$(d.l%) ' change the link
put #fl%,d.p% ' write it back
gosub init.key.rec ' init the record
lset xk$(fl%,6%)=mki$(xh%(fl%,4%)) ' allocate on stack
put #fl%,d.s% ' write it away
xh%(fl%,4%)=d.s% ' new deleted lifo rec
end if
elseif (d.s%=1%) then ' NO PARENT
rem $subtitle:'No parent, and there is a left child'
rem $page
if (d.l%<>0%) and (d.r%=0%) then ' left ONLY
get #fl%,d.l% ' get left
lrec%=cvi(xk$(fl%,2%)) ' the left grandchild
rrec%=cvi(xk$(fl%,3%)) ' the right grandchild
lset xk$(fl%,4%)=mki$(0%) ' no parent for this
put #fl%,1% ' write to 1
if (lrec%<>0%) then ' yes, theres a left gc
get #fl%,lrec% ' get the left grandchild
lset xk$(fl%,4%)=mki$(1%) ' new parent
put #fl%,lrec% ' put this record away
end if
if (rrec%<>0%) then ' yes, theres a right gc
get #fl%,rrec% ' get the right grandchild
lset xk$(fl%,4%)=mki$(1%) ' new parent
put #fl%,rrec% ' put this record away
end if
gosub init.key.rec ' init the record
lset xk$(fl%,6%)=mki$(xh%(fl%,4%)) ' allocate on stack
put #fl%,d.l% ' write it away
xh%(fl%,4%)=d.l% ' new deleted lifo rec
end if
rem $subtitle:'No parent, and there is a right child'
rem $page
if (d.r%<>0%) and (d.l%=0%) then ' right ONLY
get #fl%,d.r% ' get right
lrec%=cvi(xk$(fl%,2%)) ' the left grandchild
rrec%=cvi(xk$(fl%,3%)) ' the right grandchild
lset xk$(fl%,4%)=mki$(0%) ' no parent for this
put #fl%,1% ' write to 1
if (lrec%<>0%) then ' yes, theres a left gc
get #fl%,lrec% ' get the left grandchild
lset xk$(fl%,4%)=mki$(1%) ' new parent
put #fl%,lrec% ' put this record away
end if
if (rrec%<>0%) then ' yes, theres a right gc
get #fl%,rrec% ' get the right grandchild
lset xk$(fl%,4%)=mki$(1%) ' new parent
put #fl%,rrec% ' put this record away
end if
gosub init.key.rec ' init the record
lset xk$(fl%,6%)=mki$(xh%(fl%,4%)) ' allocate on stack
put #fl%,d.r% ' write it away
xh%(fl%,4%)=d.r% ' new deleted lifo rec
end if
rem $subtitle:'No parent and no children'
rem $page
if ((d.l%=0%) and (d.r%=0%)) then ' NO children, NO parents, lonely!
' Just in case index is large ...
close #fl% ' close the index
hn$=idx.nam$(fl%) ' Name of the index
kl%=xh%(fl%,1%) ' Key Length
call Bit.Creatq(fl%,hn$,kl%) ' Re-create the file
if aesb.fatal% then ' Fatal error opening index
call ae.error("BITKIL/BITCRE(RE)")
end if
call Bit.Open(fl%,hn$) ' Ya got it, just create it again
end if
rem $subtitle:'No parent, but both left and right children'
rem $page
if (d.l%<>0%) and (d.r%<>0%) then ' Yup, two kids
get #fl%,d.l% ' get the left
lrec%=cvi(xk$(fl%,2%)) ' the left grandchild
rrec%=cvi(xk$(fl%,3%)) ' the right grandchild
lset xk$(fl%,4%)=mki$(0%) ' no parent for this
put #fl%,1% ' write to 1
if (lrec%<>0%) then ' yes, theres a left gc
get #fl%,lrec% ' get the left grandchild
lset xk$(fl%,4%)=mki$(1%) ' new parent
put #fl%,lrec% ' put this record away
end if
if (rrec%<>0%) then ' yes, theres a right gc
get #fl%,rrec% ' get the right grandchild
lset xk$(fl%,4%)=mki$(1%) ' new parent
put #fl%,rrec% ' put this record away
end if
get #fl%,1% ' get left again
' thats where the new record is now
pnh%=1% ' last key so far
nh%=cvi(xk$(fl%,3%)) ' right key
while nh%<>0% ' keep getting
get #fl%,nh% ' get right
pnh%=nh% ' last key so far
nh%=cvi(xk$(fl%,3%)) ' right key
wend
lset xk$(fl%,3%)=mki$(d.r%) ' link deleted's right to this
put #fl%,pnh% ' write this one back
get #fl%,d.r% ' get the right one
lset xk$(fl%,4%)=mki$(pnh%) ' set the new parent
put #fl%,d.r% ' write it back
gosub init.key.rec ' init the record
lset xk$(fl%,6%)=mki$(xh%(fl%,4%)) ' allocate on stack
put #fl%,d.l% ' write it away
xh%(fl%,4%)=d.l% ' new deleted lifo rec
end if
end if
goto goodkey
rem $subtitle:'Initialize a key to blanks'
rem $page
init.key.rec: ' Initialize the key
for j%=2% to 6%
lset xk$(fl%,j%)=mki$(0%)
next j%
lset xk$(fl%,1%)=string$(xh%(fl%,1%)+10%,0%)
xh%(fl%,2)=xh%(fl%,2)-1
return
goodkey:
success%=1
goto deleted
badkey:
mrec%=0
success%=0
deleted:
end sub